package com.mallbook.controller.servlet.front;

import com.alibaba.fastjson.JSON;
import com.mallbook.controller.filter.FrontFilter;
import com.mallbook.model.exception.AddressNoException;
import com.mallbook.model.exception.GoodsStockNotException;
import com.mallbook.model.exception.ServiceException;
import com.mallbook.model.pojo.*;
import com.mallbook.model.service.AddressService;
import com.mallbook.model.service.GoodsService;
import com.mallbook.model.service.OrderService;
import com.mallbook.model.utils.MallDefaultConfig;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author 宋明松
 * @Version V1.0.0
 * @Date 2022-07-06
 */
@WebServlet("/order")
public class OrderServlet extends HttpServlet {
    private AddressService addressService = new AddressService();
    private GoodsService goodsService = new GoodsService();
    private OrderService orderService = new OrderService();
    private static final Logger logger = LoggerFactory.getLogger(OrderServlet.class);


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        String opr = req.getParameter("opr");
        switch (opr) {
            case "add":
                doAdd(req, resp);
                break;
            case "submit":
                doSubmit(req, resp);
                break;
            case "order":
                doOrder(req, resp);
                break;
            case "list":
                doList(req, resp);
                break;
            case "details":
                doDetails(req, resp);
                break;
            case "del":
                doDel(req, resp);
                break;
            case "confirm":
                doConfirm(req, resp);
                break;
        }
    }

    /**
     * 确认收货
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void doConfirm(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String oid = req.getParameter("oid");
        HttpSession session = req.getSession();
        User u = (User) session.getAttribute("USER");
        JSONObject jsonObject = new JSONObject();
        PrintWriter writer = resp.getWriter();
        try {
            orderService.updateOrderState(4, Integer.parseInt(oid), u.getId());
            jsonObject.put("msg", "ok");
        } catch (ServiceException e) {
            e.printStackTrace();
            jsonObject.put("msg", "系统繁忙，请稍后再试");
        }
        writer.print(jsonObject);
        writer.close();
    }

    /**
     * 取消订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void doDel(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String oid = req.getParameter("oid");
        HttpSession session = req.getSession();
        User u = (User) session.getAttribute("USER");
        JSONObject jsonObject = new JSONObject();
        PrintWriter writer = resp.getWriter();
        try {
            orderService.delOrder(u.getId(), Integer.parseInt(oid));
            jsonObject.put("msg", "ok");
        } catch (ServiceException e) {
            e.printStackTrace();
            jsonObject.put("msg", "系统繁忙，请稍后再试");
        }
        writer.print(jsonObject);
        writer.close();
    }

    private void doDetails(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        String oid = req.getParameter("oid");
        Orders orders = null;
        List<OrdersDetails> ordersDetailsList = null;
        List<Goods> goodsList = new ArrayList<>();
        try {
            orders = orderService.getOrdersById(Integer.parseInt(oid));
            ordersDetailsList = orders.getOrdersDetails();
            for (OrdersDetails o : ordersDetailsList
            ) {
                Goods goods = goodsService.getGoodsById(o.getBookId());
                goods.setStock(o.getBookNums()); // 将stock代替数量
                goods.setSellingPrice(o.getPrice()); // SellingPrice代替Price
                goodsList.add(goods);
            }
        } catch (ServiceException e) {
            e.printStackTrace();
        }
        // 返回多个JSON
        String jOrders = JSON.toJSONString(orders);
        String jOrdersDetailsList = JSON.toJSONString(ordersDetailsList);
//        String jGoodsList=JSON.toJSONString(goodsList);
        String bothJson = "[" + jOrders + "," + jOrdersDetailsList + "]"; //Put both objects in an array of 2 elements
        writer.print(bothJson);
        writer.close();
    }

    private void doList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String p = req.getParameter("p");
        String pSize = req.getParameter("pSize");
        String state = req.getParameter("state");
        Orders orders = new Orders();
        if (state != null && !state.isEmpty()) {
            orders.setState(Integer.parseInt(state));
        }

        String name = req.getParameter("name");
        if (name != null && !name.isEmpty()) {
            orders.setConSingnee(name);
        }
        String sTime = req.getParameter("sTime");
        if (sTime != null && !sTime.isEmpty()) {
            orders.setsTime(sTime);
        }
        String eTime = req.getParameter("eTime");
        if (eTime != null && !eTime.isEmpty()) {
            orders.seteTime(eTime);
        }

        if (pSize != null && !pSize.equals("")) {
            MallDefaultConfig.ORDER_PAGE_SIZE = Integer.parseInt(pSize);
        } else {
            MallDefaultConfig.ORDER_PAGE_SIZE = 5;
        }

        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("USER");
        orders.setUser(user);
        PrintWriter writer = resp.getWriter();
        JSONObject jsonObject = new JSONObject();
        logger.info("用户{}请求订单数据", user.getUsername());
        try {
            PageBean<Orders> ordersPageBean =
                    orderService.getOrdersByCondition(orders, user, Integer.parseInt(p));
            logger.info("用户{}请求订单数据,成功", user.getUsername());
            String json = JSON.toJSONString(ordersPageBean);
            writer.write(json);
            writer.close();
        } catch (ServiceException e) {
            logger.info("用户{}请求订单数据,失败", user.getUsername());
            e.printStackTrace();
            jsonObject.put("msg", "系统维护中");
            writer.print(jsonObject);
            writer.close();
        }

    }

    private void doOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String orderId = req.getParameter("orderid");
//        查询刚刚下的订单信息
        try {
            Orders orders = orderService.getOrdersById(Integer.parseInt(orderId));
            req.setAttribute("orders", orders);
            req.getRequestDispatcher("/WEB-INF/front/order_submit.jsp").forward(req, resp);
        } catch (ServiceException e) {
            req.setAttribute("msg", "系统维护中");
            req.getRequestDispatcher("/WEB-INF/front/order_submit.jsp").forward(req, resp);
        }

    }

    private void doSubmit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        String uid = req.getParameter("uid");
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("USER");
        logger.info("用户{}开始提交订单", user.getUsername());
        if (user == null) {
            logger.info("用户未登录");
            return;
        }

        String payMethod =
                new String(req.getParameter("payType").getBytes("iso8859-1"), StandardCharsets.UTF_8);

        String[] bookId = req.getParameterValues("gid");
        String[] bookNums = req.getParameterValues("nums");
        // 收件人信息
        String consignee = req.getParameter("consignee");
//                new String(req.getParameter("consignee").getBytes("iso8859-1"), StandardCharsets.UTF_8);
        String address = req.getParameter("province");
//                new String(req.getParameter("province").getBytes("iso8859-1"), StandardCharsets.UTF_8);
        String tel = req.getParameter("tel");

        Integer pay = null;
        if ("预存款支付".equals(payMethod)) {
            pay = 1;
        } else if ("支付宝".equals(payMethod)) {
            pay = 2;
        } else {
            pay = 3;
        }
        // 转为整形数组
        int[] bookIdInt = Arrays.stream(bookId).mapToInt(Integer::parseInt).toArray();
        int[] bookNumsInt = Arrays.stream(bookNums).mapToInt(Integer::parseInt).toArray();
        List<OrdersDetails> ordersDetailsList = new ArrayList<>();
        for (int i = 0; i < bookId.length; i++) {
            OrdersDetails ordersDetails = new OrdersDetails();
            ordersDetails.setBookId(bookIdInt[i]);
            ordersDetails.setBookNums(bookNumsInt[i]);
            ordersDetailsList.add(ordersDetails);
        }
        // 收件人信息
        Orders orders = new Orders();
        orders.setConSingnee(consignee);
        orders.setAddress(address);
        orders.setTel(tel);
        logger.info("收件人信息{}", orders);

        // 新增订单
        try {
            int orderID = orderService.addOrders(user.getId(), pay, orders, ordersDetailsList);
            logger.info("订单ID{}", orderID);
            logger.info("下单成功");
            req.getRequestDispatcher("order?opr=order&orderid=" + orderID).forward(req, resp);

        } catch (GoodsStockNotException e) {
            req.setAttribute("msg", "卖完了，下次手速要快点哦");
            req.getRequestDispatcher("/WEB-INF/front/order_add.jsp").forward(req, resp);
            logger.info("下单失败{}", "库存不足");
        } catch (AddressNoException e) {
            req.setAttribute("msg", "您还没有收货地址");
            req.getRequestDispatcher("/WEB-INF/front/order_add.jsp").forward(req, resp);
            logger.info("下单失败{}", "您还没有收货地址");
        } catch (ServiceException e) {
            req.setAttribute("msg", "系统维护中");
            req.getRequestDispatcher("/WEB-INF/front/order_add.jsp").forward(req, resp);
            logger.info("下单失败，系统出错{}", e);
        }
    }

    private void doAdd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");

        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("USER");
        logger.info("用户{}开始下单", user.getUsername());
        if (user == null) {
            logger.info("用户未登录");
            return;
        }

        String[] bookId = req.getParameterValues("goodsid");
        String[] bookNums = req.getParameterValues("num");
        // 转为整形数组
        int[] bookIdInt = Arrays.stream(bookId).mapToInt(Integer::parseInt).toArray();
        int[] bookNumsInt = Arrays.stream(bookNums).mapToInt(Integer::parseInt).toArray();

        List<Goods> goodsList = new ArrayList<>();
        for (int i = 0; i < bookId.length; i++) {
            Goods goods = goodsService.getGoodsById(bookIdInt[i]);
            goods.setStock(bookNumsInt[i]); // 使用Stock来代替nums
            goodsList.add(goods);
        }
        ;
        List<Integer> numsList = new ArrayList<>();
        for (int i = 0; i < bookNumsInt.length; i++) {
            numsList.add(bookNumsInt[i]);
        }
        ;
        logger.info("用户{}订单信息{}", user.getUsername(), goodsList);
        List<Address> addressList = addressService.getAllAddress(user.getId());
        req.setAttribute("addressList", addressList);
        req.setAttribute("goodsList", goodsList);
//        req.setAttribute("nums", numsList);
        req.getRequestDispatcher("/WEB-INF/front/order_add.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
